/**
 *  Coded by Danshin TV based on an example found in the internet.
 *  No copyright. Free software and stuff like that
 */

//include java.security.*;
package org.gpswalker.sys.server.misc;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.security.MessageDigest;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;

// import org.jdom.Element;

// import ru.tr0.dic.login.NotLoggedInException;

/**
 * This is a class for doing things with different strings. It can produce md5
 * hashes of strings, turn aTrhowable into a String...
 */

public class Misc {

	public static int[] getIntArrFromReq(ServletInOut sio_, String param_) {
		String a[];
		a = sio_.getRequest().getParameterValues(param_);
		int l = a.length;
		int[] ret = new int[l];
		for (int i = 0; i < l; i++) {
			ret[i] = Misc.parseInt(a[i]);
		}
		return ret;
	}
	
	public static void printStackTrace(Throwable e, PrintWriter pw) {
	    pw.print(getStackTrace(e));
	}

	/**
	 * Repeats the given input string s the n number of times. To be changed to
	 * use StringBuffer instead.
	 * 
	 * @param s
	 * @param n
	 * @return the imploded string consisting of the n of initial strings;
	 */
	public static String conc(String s, int n) {
		if ((n <= 0) || (s.equals(""))) {
			return "";
		}
		StringBuffer s2 = new StringBuffer();
		for (; n > 0; n--) {
			s2.append(s);
		}
		return s2.toString();
	}

	/**
	 * implodes the input array into a string of values separated by the
	 * separator;
	 * 
	 * @param input
	 * @param separator
	 * @return the imploded string;
	 */
	public static String implode(String[] input, String separator) {
		if (input == null || input.length == 0) {
			throw new NullPointerException(
					"The provided array is null or empty");
		}

		if (input.length == 1) {
			return input[0];
		}

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < input.length - 1; i++) {
			sb.append(input[i]).append(separator);
		}
		sb.append(input[input.length - 1]);

		return sb.toString();
	}

	/**
	 * Implodes two arrays of strings by means of two separators the following
	 * way: <br />
	 * <code>one[n] + sepOne + two[n] + sepTwo + one[n+1]...</code>
	 * 
	 * @param one
	 * @param two
	 * @param sepOne
	 * @param sepTwo
	 * @return imploded string
	 */
	public static String implode(String[] one, String[] two, String sepOne,
			String sepTwo) {
		if (one.length != two.length) {
			throw new RuntimeException("The lengths of the strings dont match!");
		}
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < one.length - 1; i++) {
			sb.append(one[i]).append(sepOne).append(two[i]).append(sepTwo);
		}
		sb.append(one[one.length - 1]).append(sepOne).append(one.length - 1)
				.append(sepTwo);

		return sb.toString();
	}

	/**
	 * Returns an integer value of the specified param from HttpServletRequest.
	 * 
	 * @param req
	 * @param param
	 * @return
	 */

	public static int getIntFromReq(HttpServletRequest req, String param) {
		String s = getStringFromReq(req, param);
		if (s.equals("")) {
			return 0;
		}
		return Integer.parseInt(s);
	}

	/**
	 * Turns a throwable into a string that can be used in logging or in
	 * outputting to XML.
	 * 
	 * @param aThrowable
	 * @return String
	 */
	public static String getStackTrace(Throwable aThrowable) {
		final Writer result = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(result);
		aThrowable.printStackTrace(printWriter);
		return result.toString().replace(">", "&gt;").replace("<", "&lt;");
	}

	public static String getStringFromReq(HttpServletRequest req, String param) {
		String s = req.getParameter(param);
		s = (s == null) ? "" : s.trim();
		return s;
	}

	private static String hex(byte[] array) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < array.length; ++i) {
			sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(
					1, 3));
		}
		return sb.toString();
	}

	// Functions to get parameters from the HttpServletRequest. Two
	// possibilities:
	// int; or
	// String;

	/**
	 * returns an md5 hash of the message.
	 * 
	 * @param message
	 * @return String md5
	 */
	public static String md5(String message) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			return hex(md.digest(message.getBytes("CP1252")));
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * This function takes a string as an input and creates an XML element from
	 * it that contains elements corresponding to the paragraphs in that string.
	 * So whenever a \r occurs, it means, that a new paragraph has begun, and it
	 * will be enclosed into &lt;par&gt; tags;
	 * 
	 * More things to be considered are to come. For example, we must somehow
	 * deal with bold text, italic, underline, strikeout, hrefs and who knows
	 * what else.
	 * 
	 * @param s
	 *            an input string that must be turned into xml
	 * @return Element the resulting element from that turning.
	 */

//	public static Element setTextToXML(String s) {
//		Element text = new Element("text");
//		StringTokenizer st = new StringTokenizer(s, "\r");
//		while (st.hasMoreTokens()) {
//			String s2 = st.nextToken().toString();
//			s2 = s2.trim();
//			text.addContent(new Element("par").addContent(s2));
//		}
//		return text;
//	}

	public static int getRsLength(ResultSet rs) throws SQLException {
		rs.last();
		int length = rs.getRow();
		rs.beforeFirst();
		return length;
	}

	/**
	 * This is a function for getting substrings from strings in an easier and
	 * more convenient way. It takes a String and an int as parameters and
	 * returns a string consisting of the number of characters you specified by
	 * the int OR FEWER, if the string itself is shorter, or if the last
	 * character of the sequence is a space character. In other words, it first
	 * trims the string, if the string is longer than the int you provided, it
	 * chops it, and trims it again.
	 * 
	 * @param s
	 *            an input String
	 * @param length
	 *            the length of the string you want to get. Note, that the
	 *            actual returned string MAY be shorter, if the input string is
	 *            shorter or if the last chars of the substring are spaces
	 * @return substring of the given string
	 */
	public static String substr(String s, int length) {
		s = s.trim();
		int l = s.length();
		l = (l < length) ? l : length;
		return s.substring(0, l).trim();
	}

	public static void handleNotLoggedInException(ServletInOut sio) {
		sio.println("you are not logged in!!!");
	}

//	public static void userLoggedIn(ServletInOut sio)
//			throws NotLoggedInException {
//		if (sio.getUserInfo().getInt("id") == 1) {
//			throw new NotLoggedInException("You are not loggedIn");
//		}
//	}

	public static int parseInt(String s) {
		if (s.equals("")) {
			return 0;
		}
		return Integer.parseInt(s);
	}

	/**
	 * this thing returns a default language of the whole system. It needs be
	 * replaced by a normal getter in a singleton that would return this value
	 * from the db or something
	 * 
	 * @return the int representing the system language of our dictionaries. As
	 *         yet, it returns 1.
	 */
	public static int getSysLang() {
		return 1;
	}

	/**
	 * This method is needed for use until we haven't made the private messaging
	 * system. To be replaced thereupon
	 * 
	 * @param c
	 *            the name of the caller class
	 */
//	public static void sendInnerNotification(String c) {
//		Logger
//				.getInstance()
//				.log(
//						"Class "
//								+ c
//								+ " called method sendInnerNotification(String c)");
//		return;
//	}

	/**
	 * This method is needed for use until we haven't made the private messaging
	 * system. To be replaced thereupon
	 * 
	 * @param c
	 *            the name of the caller class
	 */
//	public static void sendEmailNotification(String c) {
//		Logger
//				.getInstance()
//				.log(
//						"Class "
//								+ c
//								+ " called method sendEmailNotification(String c)");
//		return;
//	}

	/**
	 * Empty constructor so that no one could create an instance of
	 * <code>Misc</code>
	 */
	private Misc() {
		// lskd
	}

}